<?php

namespace App\Http\Controllers;

use App\Exceptions\InvalidRequestException;
use App\Models\Category;
use App\Models\OrderItem;
use App\Models\Product;
use App\Services\CategoryService;
use Illuminate\Http\Request;

class ProductsController extends Controller
{
    /**
     * 商品列表
     *
     * @param  Request  $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index(Request $request)
    {
        //创建一个查询构造器
        $builder = Product::query()->where('on_sale', true);
        // 判断是否有提交 search 参数 ， 如果有就赋值给 $search 变量
        // search 参数用来模糊搜索商品
        if ($search = $request->input('search', '')) {
            $like = '%'.$search.'%';
            // 模糊搜索商品 标题、 商品详情、 SKU 标题、SKU 描述
            $builder->where(
                function ($query) use ($like) {
                    $query->where('title', 'like', $like)
                        ->orWhere('description', 'like', $like)
                        ->orWhereHas(
                            'skus',
                            function ($query) use ($like) {
                                $query->where('title', 'like', $like)
                                    ->orWhere('description', 'like', $like);
                            }
                        );
                }
            );
        }
        if ($request->input('category_id') && $category = Category::query()->find($request->input('category_id'))) {
            // 如果这是一个父类目
            if ($category->is_directory) {
                // 则赛选出该父类目下的所有子级类目商品
                $builder->whereHas(
                    'category',
                    function ($query) use ($category) {
                        $query->where('path', 'like', $category->path.$category->id.'-%');
                    }
                );
            } else {
                // 这不是一个父类目
                $builder->where('category_id', $category->id);
            }
        }
        // 是否有提交 order 参数， 如果有 那么久赋值给 $order 变量
        // order 参数用来控制商品排序规则
        if ($order = $request->input('order', '')) {
            // 是否是以 _asc 或者 _desc 结尾
            if (preg_match('/^(.+)_(asc|desc)$/', $order, $m)) {
                // 如果字符串开头的是 3 个字符之一， 说明是合法的排序值
                if (in_array($m[1], ['price', 'sold_count', 'rating'])) {
                    // 根据传入的排序值来构建排序参数
                    $builder->orderBy($m[1], $m[2]);
                }
            }
        }
        $products = $builder->paginate(16);

        return view('products.index', ['products' => $products, 'filters' => ['search' => $search, 'order' => $order], 'category' => $category ?? null]);
    }

    /**
     * 商品详情
     *
     * @param  Product  $product
     * @param  Request  $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     * @throws InvalidRequestException
     */
    public function show(Product $product, Request $request)
    {
        // 判断商品是否已经上架， 如果没有 抛出异常
        if (!$product->on_sale) {
            throw new InvalidRequestException('商品为上架');
        }
        $favored = false;
        // 用户未登录的时候是 null ， 已登录时返回的是对应的用户对象
        if ($user = $request->user()) {
            // 从当前用户已收藏的商品中搜索 id 为当前 id 的商品
            // boolval() 函数是用于把值转为布尔值
            $favored = boolval($user->favoriteProducts()->find($product->id));
        }
        $reviews = OrderItem::query()->with(['order.user', 'productSku'])->where(
            'product_id',
            $product->id
        )->whereNotNull('reviewed_at')->orderBy('reviewed_at', 'desc')->limit(10)->get();

        return view('products.show', ['product' => $product, 'favored' => $favored, 'reviews' => $reviews]);
    }

    /**
     * 用户收藏商品
     *
     * @param  Product  $product
     * @param  Request  $request
     * @return array
     */
    public function favor(Product $product, Request $request)
    {
        $user = $request->user();
        if ($user->favoriteProducts()->find($product->id)) {
            return [];
        }

        $user->favoriteProducts()->attach($product);

        return [];
    }

    /**
     * 新增收藏
     *
     * @param  Product  $product
     * @param  Request  $request
     * @return array
     */
    public function disfavor(Product $product, Request $request)
    {
        $user = $request->user();
        $user->favoriteProducts()->detach($product);

        return [];
    }

    /**
     * 我的收藏
     *
     * @param  Request  $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function favorites(Request $request)
    {
        $products = $request->user()->favoriteProducts()->paginate(16);

        return view('products.favorites', ['products' => $products]);
    }
}
